/**
 *
 * Copyright 2009 Marco Speranza <marco.speranza79@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.commons.database.jconnectionpool;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
import javax.sql.PooledConnection;

import org.apache.log4j.Logger;

public class PooledConnectionStub implements PooledConnection {

    Logger log = Logger.getRootLogger();
    ConnectionEventListener listener;

    int throwsSqlException = 0;

    public PooledConnectionStub(int throwsGetConnectionSqlException) {
	throwsSqlException = throwsGetConnectionSqlException;
    }

    public void addConnectionEventListener(ConnectionEventListener listener) {
	log.trace("addConnectionEventListener: " + listener);
	this.listener = listener;
    }

    synchronized void callErrorListener(SQLException t) {
	ConnectionEvent connectionevent = new ConnectionEvent(this, t);
	ConnectionPoolDataSourceStub.logialConnectionCount--;
	ConnectionPoolDataSourceStub.phisicalConnectionCount--;
	if (listener != null)
	    listener.connectionErrorOccurred(connectionevent);
    }

    synchronized void callListener() {
	ConnectionEvent connectionevent = new ConnectionEvent(this);
	ConnectionPoolDataSourceStub.logialConnectionCount--;
	if (listener != null)
	    listener.connectionClosed(connectionevent);
    }

    public void close() throws SQLException {
	log.debug("fisical connection close. close()");
	ConnectionPoolDataSourceStub.phisicalConnectionCount--;
    }

    synchronized public Connection getConnection() throws SQLException {
	ConnectionPoolDataSourceStub.phisicalConnectionCount++;
	ConnectionPoolDataSourceStub.logialConnectionCount++;
	if (throwsSqlException == 1) {
	    callErrorListener(new SQLException(" FOR TEST: getConnectionError."));
	    throw new SQLException(" FOR TEST: getConnectionError.");
	}
	if (throwsSqlException == 2) {
	    callErrorListener(new SQLException(" FOR TEST: getConnectionError."));
	    throwsSqlException = 0;
	    throw new SQLException(" FOR TEST: getConnectionError.");
	}
	log.trace("getConnection()");

	return new ConnectionStub(this);
    }

    public void removeConnectionEventListener(ConnectionEventListener listener) {
	log.trace("removeConnectionEventListener: " + listener);
	this.listener = null;
	;
    }


}
